/*
 * Copyright (c)  16-11-3 上午10:07
 * Author: oumin
 */

package com.avic.rong.publishVideo.Record;

import android.app.Activity;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.media.MediaMetadataRetriever;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.Toast;


import com.avic.rong.R;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

/**
 * Created by oumin on 2016/11/3.
 */

public class RecordVideoControl implements SurfaceHolder.Callback, MediaRecorder.OnInfoListener, MediaRecorder.OnErrorListener, Runnable {
    private final int MAXTIME = 20000;//最大录制时间

    private int mCountTime = 0;
    private int defaultVideoFrameRate = 25;//默认的视频帧率
    private int previewWidth = 640;//预览宽
    private int previewHeight = 480;//预览高
    final String TAG = RecordVideoControl.class.getSimpleName();
    private String localPath = "";
    Activity mAct;
    private MediaRecorder mediaRecorder;


    private boolean mIsPreviewing;
    private int mCameraId;
    public Camera mCamera;
    SurfaceHolder mSurfaceHolder;
    SizeSurfaceView mSurfaceView;
    boolean isRecording = false;
    CallBack mCallBack;

    public interface CallBack {
        void RecordingFinish(String path);

        void UpdateOfTime(int precent);
    }


    public RecordVideoControl(Activity act, String path, SizeSurfaceView surfaceView, CallBack mCallBack) {
        mAct = act;
        mSurfaceView = surfaceView;
        mSurfaceView.setUserSize(true);
        mSurfaceHolder = mSurfaceView.getHolder();
        this.mCallBack = mCallBack;
        localPath = path;
        mIsPreviewing = false;

        mCamera = null;
        mSurfaceHolder.addCallback(this);
        if (Build.VERSION.SDK_INT > 8) {
//            if (Camera.getNumberOfCameras() > 1) {
//                mCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;//前置摄像
//            } else {
//                mCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;//后置摄像
//            }
            mCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;//后置摄像
        }
    }


    public void destroyCamera() {
        if (mCamera != null) {
            if (mIsPreviewing) {
                mCamera.stopPreview();
                mIsPreviewing = false;
                mCamera.setPreviewCallback(null);
                mCamera.setPreviewCallbackWithBuffer(null);
            }
            mCamera.release();
            mCamera = null;
        }
    }

    private void setCameraParameter() {
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(previewWidth, previewHeight);

        setFocusContinuousMode(parameters);
        mCamera.setParameters(parameters);
    }

    public void ChangeCamera(final View view) {
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                if (v != null)
                    v.setEnabled(false);
                changeCamera();
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (v != null)
                            v.setEnabled(true);
                    }
                }, 1000);
            }
        });

    }

    @SuppressWarnings("deprecation")
    private void changeCamera() {
        if (isRecording) {
            Toast.makeText(mAct, R.string.record_cant_change, Toast.LENGTH_SHORT).show();
            return;
        }
        if (Build.VERSION.SDK_INT < 9) {
            return;
        }
        int cameraid = 0;
        if (Camera.getNumberOfCameras() > 1) {
            if (mCameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
                cameraid = Camera.CameraInfo.CAMERA_FACING_FRONT;
            } else {
                cameraid = Camera.CameraInfo.CAMERA_FACING_BACK;
            }
        } else {
            cameraid = Camera.CameraInfo.CAMERA_FACING_BACK;
        }
        if (mCameraId == cameraid) {
            return;
        } else {
            mCameraId = cameraid;
        }

        destroyCamera();
        try {
            mCamera = Camera.open(mCameraId);

            if (mCamera != null) {
                startCameraPreview(mSurfaceHolder);
            }

        } catch (Exception e) {
            destroyCamera();
        }

    }

    private void startCameraPreview(SurfaceHolder holder) {
        mIsPreviewing = false;
        setCameraParameter();
        mCamera.setDisplayOrientation(90);
        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            destroyCamera();
            return;
        }
        mCamera.startPreview();
        mIsPreviewing = true;
        mSurfaceView.setVideoDimension(previewHeight, previewWidth);
        mSurfaceView.requestLayout();
    }

    private void setFocusContinuousMode(Camera.Parameters parameters) {
        if (Build.VERSION.SDK_INT < 9) {
            return;
        }
        List<String> supportedFocus = parameters.getSupportedFocusModes();
        if (CameraSetting.isSupported(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO, supportedFocus)) {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
        }
    }


    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        try {
            destroyCamera();
            releaseRecorder();
        } catch (Exception e) {
        }

    }


    @Override
    public void surfaceCreated(final SurfaceHolder holder) {

    }

    @Override
    public void surfaceChanged(final SurfaceHolder holder, int arg1, int arg2, int arg3) {
        Log.d(TAG, "surfaceChanged execute");
        try {
            mSurfaceHolder = holder;
            if (holder.getSurface() == null) {
                return;
            }
            if (mCamera == null) {
                if (Build.VERSION.SDK_INT < 9) {
                    mCamera = Camera.open();
                } else {
                    mCamera = Camera.open(mCameraId);
                }
            }
            if (mCamera != null)
                mCamera.stopPreview();
            mIsPreviewing = false;
            startCameraPreview(mSurfaceHolder);
            handleSurfaceChanged(mCamera);
        } catch (Exception e) {
        }

    }


    /**
     * 录制回调接口回调
     *
     * @param mr
     * @param what
     * @param extra
     */
    @Override
    public void onInfo(MediaRecorder mr, int what, int extra) {
        Log.v(TAG, "onInfo");
        if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
            Log.v(TAG, "最大录制时间已到");
            stopRecording(true);
        }
    }

    /**
     * 录制回调错误回调
     *
     * @param mr
     * @param what
     * @param extra
     */
    @Override
    public void onError(MediaRecorder mr, int what, int extra) {
        Log.e(TAG, "recording onError:");
        Toast.makeText(mAct, "录制失败，请重试", Toast.LENGTH_SHORT).show();
        stopRecording(false);

    }


    /**
     * 释放mediaRecorder
     */
    private void releaseRecorder() {
        if (mediaRecorder != null) {
            mediaRecorder.release();
            mediaRecorder = null;
        }
    }

    /**
     * 开始录制
     *
     * @return
     */
    public boolean startRecording() {
        isRecording = true;
        mCountTime = 0;
        releaseRecorder();
//        Toast.makeText(mAct, R.string.record_cant_change,Toast.LENGTH_SHORT).show();
        mCamera.stopPreview();
        mCamera.unlock();
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setCamera(mCamera);
//        mCamera.setDisplayOrientation(90);
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        //设置分辨率，应设置在格式和编码器设置之后
        mediaRecorder.setVideoSize(previewWidth, previewHeight);
        if (mCameraId == 1) {
            mediaRecorder.setOrientationHint(270);
        } else {
            mediaRecorder.setOrientationHint(90);
        }
        customMediaRecorder();
//        try {
//            mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
//        } catch (Exception e) {
//            Log.e(TAG, "设置质量出错:" + e.getMessage());
//            customMediaRecorder();
//        }

        // 设置帧速率，应设置在格式和编码器设置
        mediaRecorder.setVideoFrameRate(defaultVideoFrameRate);
        mediaRecorder.setOnInfoListener(this);
        mediaRecorder.setOnErrorListener(this);
        // 设置最大录制时间
        mediaRecorder.setMaxDuration(10000);
        mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
        mediaRecorder.setOutputFile(localPath);
        try {
            mediaRecorder.prepare();
            mediaRecorder.start();
            new Thread(this).start();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 停止录制
     */
    public void stopRecording(boolean isSucessed) {
        if (!isRecording) {
            return;
        }

        try {
            if (mediaRecorder != null && isRecording) {
                isRecording = false;
                mediaRecorder.stop();


                try {
                    Thread.sleep(100);
                } catch (InterruptedException e1) {

                }

                mediaRecorder.release();
                mediaRecorder = null;
                mCountTime = 0;
                if (isSucessed) {
                    if (mCallBack != null) {
                        mCallBack.RecordingFinish(localPath);
                    }
                } else {
                    updateCallBack(0);
                }

            }
        } catch (Exception e) {
            updateCallBack(0);


            Log.e(TAG, "stopRecording error:" + e.getMessage());
        }
    }

    private void updateCallBack(final int present) {
        if (mAct != null && !mAct.isFinishing()) {
            mAct.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (mCallBack != null) {
                        mCallBack.UpdateOfTime(present);
                    }
                }
            });
        }
    }

    /**
     * 自定义的设置mediaeecorder 这里设置视频质量最低  录制出来的视频体积很小 对质量不是要求不高的可以使用
     */
    public void customMediaRecorder() {
        if (mediaRecorder != null) {
            mediaRecorder.setVideoEncodingBitRate(10 * 1024 * 1024);
        }

    }

    private void handleSurfaceChanged(Camera mCamera) {
        boolean hasSupportRate = false;
        List<Integer> supportedPreviewFrameRates = mCamera.getParameters()
                .getSupportedPreviewFrameRates();
        if (supportedPreviewFrameRates != null
                && supportedPreviewFrameRates.size() > 0) {
            Collections.sort(supportedPreviewFrameRates);
            for (int i = 0; i < supportedPreviewFrameRates.size(); i++) {
                int supportRate = supportedPreviewFrameRates.get(i);

                if (supportRate == 25) {
                    hasSupportRate = true;
                }

            }
            if (hasSupportRate) {
                defaultVideoFrameRate = 25;
            } else {
                defaultVideoFrameRate = supportedPreviewFrameRates.get(0);
            }

        }

//        // 获取相机提供的所有分辨率
//        List<Camera.Size> resolutionList = RecorderUtils.getResolutionList(mCamera);
//        if (resolutionList != null && resolutionList.size() > 0) {
//            Collections.sort(resolutionList, new RecorderUtils.ResolutionComparator());
//            Camera.Size previewSize = null;
//            boolean hasSize = false;
//            // 使用 640*480 如果相机支持的话
//            for (int i = 0; i < resolutionList.size(); i++) {
//                Camera.Size size = resolutionList.get(i);
//                Log.v(TAG, "width:" + size.width + "   height:" + size.height);
//                if (size != null && size.width == 640 && size.height == 480) {
//                    previewSize = size;
//                    previewWidth = previewSize.width;
//                    previewHeight = previewSize.height;
//                    hasSize = true;
//                    break;
//                }
//            }
//            //如果相机不支持上述分辨率，使用中分辨率
//            if (!hasSize) {
//                int mediumResolution = resolutionList.size() / 2;
//                if (mediumResolution >= resolutionList.size())
//                    mediumResolution = resolutionList.size() - 1;
//                previewSize = resolutionList.get(mediumResolution);
//                previewWidth = previewSize.width;
//                previewHeight = previewSize.height;
//            }
//        }
    }

    @Override
    public void run() {
        while (isRecording) {
            updateCallBack(mCountTime * 100 / MAXTIME);
            try {
                mCountTime += 100;
                Thread.sleep(100);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static Bitmap getVideoFristImage(String path) {
        MediaMetadataRetriever media = new MediaMetadataRetriever();
        media.setDataSource(path);
        Bitmap bitmap = media.getFrameAtTime();
        return bitmap;
    }
}
